package com.sfzlot.dev.netty.server.server.handler;

import com.sfzlot.dev.netty.bean.Message;
import com.sfzlot.dev.netty.bean.bussiness.Product;
import com.sfzlot.dev.netty.bean.bussiness.Subdivide;
import com.sfzlot.dev.netty.bean.command.PowerSwitchCommand;
import com.sfzlot.dev.netty.bean.data.DeviceStatusOutData;
import com.sfzlot.dev.netty.bean.data.ObjectData;
import com.sfzlot.dev.netty.bean.identifier.ResponseIdentifier;
import com.sfzlot.dev.netty.constant.Constant;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.AttributeKey;
import io.netty.util.ReferenceCountUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Created by xieqc on 2017/5/27.
 */
public class ServerHandler extends ChannelInboundHandlerAdapter {

	final static Logger logger = LoggerFactory.getLogger(ServerHandler.class);

	public static ConcurrentMap<String, Channel> connectMap = new ConcurrentHashMap<String, Channel>();

//	@Override 
//    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause){ 
//		cause.printStackTrace();
//		logger.debug("======exceptionCaught========"+cause.getMessage());                         
//    } 

	/**
	 * channel失效处理,客户端下线或者强制退出等任何情况都触发这个方法
	 */
	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		String vin = ctx.channel().attr(AttributeKey.<String>valueOf(Constant.VIN_KEY)).get();
		ServerHandler.connectMap.remove(Constant.CHANNEL + vin); // 删除连接
		logger.info("断开连接：" + vin);
		super.channelInactive(ctx);
		ctx.close();
	}

	@Override
	public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
		if (evt instanceof IdleStateEvent) {
			IdleStateEvent e = (IdleStateEvent) evt;
			String vin = ctx.channel().attr(AttributeKey.<String>valueOf(Constant.VIN_KEY)).get();
			switch (e.state()) {
			case READER_IDLE:
				logger.info("======READER_IDLE========vin:{}", vin);
				ctx.close();
				break;
			case WRITER_IDLE:
				logger.info("======WRITER_IDLE========vin:{}", vin);
				break;
			case ALL_IDLE:
				logger.info("======ALL_IDLE========vin:{}", vin);
				break;
			default:
				break;
			}
		}
	}

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		try {
			Message message = (Message) msg;
			switch (message.getIndustry()) {// 行业大类
			case SMARTFAMILY: // 智慧家庭
				switch ((Subdivide.SmartFamily) message.getSubdivide()) {
				case SMARTHOME: // 智能家居
					switch ((Product.SmartHome) message.getProduct()) {
					case POWERSWITCH:
						responseSwitchCommand(ctx, message);
						break;
					default:
						throw new Exception("产品类型不存在");
					}
					break;
				default:
					throw new Exception("行业细分不存在");
				}
				break;
			case RETAILSERVICE: // 零售服务
				break;
			default:
				throw new Exception("行业大类不存在");
			}
		} finally {
			ReferenceCountUtil.safeRelease(msg);
		}
	}

	/**
	 * 智能开关指令的响应
	 * 
	 * @param ctx
	 * @param message
	 * @throws Exception
	 */
	private void responseSwitchCommand(ChannelHandlerContext ctx, Message message) throws Exception {
		String type = "（智能开关）" + message.getVin() + "：";
		if (message.getCommandIdentifier() == PowerSwitchCommand.DEVICE_STATUS) {
			logger.info("------------{}设备状态上报-V{}版本", type , message.getVersion());
			responseStatus(ctx, message);
		} else if (message.getCommandIdentifier() == PowerSwitchCommand.DEVICE_LOGOUT) {
			logger.info("------------{}设备登出", type);
			responseNoDataCommon(ctx, message);
		} else if (message.getCommandIdentifier() == PowerSwitchCommand.DEVICE_SERVER) {
			logger.info("------------{}更改服务器", type);
			ctx.close();
		} else if (message.getCommandIdentifier() == PowerSwitchCommand.DEVICE_SETTING) {
			logger.info("------------{}更改WIFI账号和密码", type);
			ctx.close();
		} else if (message.getCommandIdentifier() == PowerSwitchCommand.DEVICE_INFO) {
			logger.info("------------{}获取终端信息", type);
		} else if (message.getCommandIdentifier() == PowerSwitchCommand.DEVICE_SWITCH) {
			logger.info("------------{}物理开关是否有效", type);
		} else if (message.getCommandIdentifier() == PowerSwitchCommand.DEVICE_START) {
			logger.info("------------{}开关-通电", type);
		} else if (message.getCommandIdentifier() == PowerSwitchCommand.DEVICE_STOP) {
			logger.info("------------{}开关-断电", type);
		} else if (message.getCommandIdentifier() == PowerSwitchCommand.DEVICE_RESET) {
			logger.info("------------{}重置设备", type);
			ctx.close();
		}

	}

	/**
	 * 设备状态上报响应报文
	 * 
	 * @param ctx
	 * @param message
	 */
	private void responseStatus(ChannelHandlerContext ctx, Message message) {
		message.setResponseIdentifier(ResponseIdentifier.SUCCESS);
		DeviceStatusOutData data = new DeviceStatusOutData();
		data.setDataCollectTime(new Date());
		message.setData(data);
		ctx.writeAndFlush(message);
	}

	/**
	 * data没有数据，只返回成功标识就行
	 * 
	 * @param ctx
	 * @param message
	 */
	private void responseNoDataCommon(ChannelHandlerContext ctx, Message message) {
		message.setResponseIdentifier(ResponseIdentifier.SUCCESS);
		ObjectData data = new ObjectData();
		byte[] dataBytes = new byte[0];
		data.setBytes(dataBytes);
		message.setData(data);
		ctx.writeAndFlush(message);
	}

}
